home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 42
/
Amiga Format AFCD42 (Issue 126, Aug 1999).iso
/
-serious-
/
programming
/
c
/
awin
/
awindemo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-17
|
14KB
|
484 lines
/* awindemo.c
Simple example on how to use awin.
Has three effects, dummy 16bit `pseudo'plasma,
8bit rotatezoomer and tunnel.
compiled with ppc-amigaos-gcc 2.7.2.1:
rotzoom runs ~198fps in 64x48 dbuffer off pal screen on 603p@240/060,
~138fps 128x96, ~65fps 256x180 and ~45fps 320x240
tunnel runs ~109fps (slow because of 128k table lookup),
~88fps 128x96, ~51fps 256x180 and ~38fps 320x240
all effects are calculating 320x240 chunky framebuffer.
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
#include "awin.h"
#define AWINDEMOVERSION "awindemo 1.0.13"
#define PLASMA_TIME 5000
#define PLASMA_WIDTH 320
#define PLASMA_HEIGHT 240
#define PLASMA_DEPTH 16
#define ROTZOOM_TIME 20000
#define ROTZOOM_WIDTH 320
#define ROTZOOM_HEIGHT 240
#define ROTZOOM_DEPTH 8
#define TUNNEL_TIME 20000
#define TUNNEL_WIDTH 320
#define TUNNEL_HEIGHT 240
#define TUNNEL_DEPTH 8
#define DEF_WIDTH 320
#define DEF_HEIGHT 240
#define SINTAB90 1024
#define SINTAB360 (SINTAB90*4)
unsigned long __stack=20480;
#if defined(AW_PPC)
void __chkabort(void);
void __chkabort(void){}
#else
void __regargs __chkabort(void);
void __regargs __chkabort(void){}
#endif
/* this plasma isn't really plasma but simple routine to
generate 16bit test chunky */
#define limr(x) (((x)<0)?0:(((x)>31)?31:(x)))
#define limg(x) (((x)<0)?0:(((x)>63)?63:(x)))
#define limb(x) (((x)<0)?0:(((x)>31)?31:(x)))
#define truncr(x) ((x)&31)
#define truncg(x) ((x)&63)
#define truncb(x) ((x)&31)
#define torgb565(r,g,b) ((r)<<11|(g)<<5|(b))
void plasma(struct awchunky *chunky,ULONG time) {
ULONG x,y,
*p=(ULONG *)chunky->framebuffer;
ULONG r,g,b;
r=time/64+1;
g=time/32+3;
b=-(time/16+5);
for (y=0; y<chunky->height; y++) {
r+=(((y+time/100)/13)&7)-3;
g+=7-((y/11)&15);
b+=((y/7)&31)-15;
for (x=0; x<chunky->width_align; x+=8)
*p++=
torgb565(truncr(r),truncg(g),truncb(b))<<16|
torgb565(truncr(r+1),truncg(g+1),truncb(b+1)),
*p++=
torgb565(truncr(r+2),truncg(g+2),truncb(b+2))<<16|
torgb565(truncr(r+3),truncg(g+3),truncb(b+3)),
*p++=
torgb565(truncr(r+4),truncg(g+4),truncb(b+4))<<16|
torgb565(truncr(r+5),truncg(g+5),truncb(b+5)),
*p++=
torgb565(truncr(r+6),truncg(g+6),truncb(b+6))<<16|
torgb565(truncr(r+7),truncg(g+7),truncb(b+7)),
r+=8,g+=8,b+=8;
}
}
LONG *init_sintab(void) {
LONG *sintab,i;
sintab=malloc(sizeof(LONG)*(SINTAB360+SINTAB90));
if (!sintab) {
printf("no memory for sintab\n");
return NULL;
}
for(i=0; i<(SINTAB360+SINTAB90); i++) {
sintab[i]=sin(M_PI/180.0*i*360.0/SINTAB360)*32768;
}
return sintab;
}
/* this routine "taken" from QMap :) */
void rotzoom(struct awchunky *chunky,ULONG time,
ULONG *alpha,LONG *sintab,UBYTE *pic) {
ULONG x,y,tx,ty,tx2,ty2,
*p=(ULONG *)chunky->framebuffer;
LONG aktsin,aktcos;
aktsin=2*sintab[*alpha&(SINTAB360-1)];
aktcos=2*sintab[(*alpha&(SINTAB360-1))+SINTAB90];
/* spend 10 seconds on SINTAB360 degrees */
*alpha=time/(10000.0/SINTAB360);
tx2=-100*sintab[(5*(*alpha)+23)&(SINTAB360-1)];
ty2=-100*sintab[((7*(*alpha)+71)&(SINTAB360-1))+SINTAB90];
for (y=0; y<chunky->height; y++) {
tx=tx2;
ty=ty2;
for (x=0; x<chunky->width_align; x+=16)
*p++=pic[((ty>>9)&(0x7f<<7))+((tx>>16)&0x7f)]<<24|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<16|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<8|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)],
*p++=pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<24|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<16|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<8|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)],
*p++=pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<24|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<16|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<8|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)],
*p++=pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<24|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<16|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)]<<8|
pic[(((ty+=aktcos)>>9)&(0x7f<<7))+(((tx+=aktsin)>>16)&0x7f)],
ty+=aktcos, tx+=aktsin; /* !! */
tx2+=aktcos;
ty2-=aktsin;
aktsin-=1<<8;
aktcos+=1<<8;
}
}
UWORD *init_tunnel(void) {
UWORD *tunneltab;
LONG x,y;
ULONG xx,yy;
UWORD *tab;
tunneltab=malloc(TUNNEL_WIDTH*TUNNEL_HEIGHT*sizeof(UWORD));
if (!tunneltab) {
printf("no memory for tunneltab\n");
return NULL;
}
/* again this stuff shamelesly ripped. */
tab=tunneltab;
for (y=TUNNEL_HEIGHT/2; y>-TUNNEL_HEIGHT/2; y--) {
for (x=-TUNNEL_WIDTH/2; x<TUNNEL_WIDTH/2; x++) {
if (x | y) {
yy = (int) (6000 / sqrt((double)(x*x+y*y))) & 0xff;
xx = (int) (atan2((double)y, (double)x) * (256/M_PI)) &0xff;
*tab++ = yy<<8 | xx;
} else {
*tab++ = 0;
}
}
}
return tunneltab;
}
UBYTE *init_texture(struct awfile *pic) {
UBYTE *texture=NULL;
if (pic) {
if (pic->size!=256*256) {
printf("tunnel texture size not 256*256\n");
awfreefile(pic);
return NULL;
}
texture=malloc(256*256*2);
if (!texture) {
printf("no memory for texture\n");
return NULL;
}
/* copy texture to mem twice */
memcpy(texture+0*256*256,pic->data,256*256);
memcpy(texture+1*256*256,pic->data,256*256);
awfreefile(pic);
}
return texture;
}
void tunnel(struct awchunky *chunky,ULONG time,
UWORD *position,UWORD *tunneltab,LONG *sintab,UBYTE *texture) {
ULONG cnt=(chunky->width_align>>4)*chunky->height,
index=0;
ULONG *p=(ULONG *)chunky->framebuffer;
UBYTE *t=&texture[*position];
/* move along in texture */
*position=
((time/4-sintab[(time/3+SINTAB90)&(SINTAB360-1)]/256)&0xff)<<8|
((time/32+sintab[(time/2)&(SINTAB360-1)]/128)&0xff);
while (cnt--)
*p++=t[tunneltab[index+0]]<<24 | t[tunneltab[index+1]]<<16 |
t[tunneltab[index+2]]<<8 | t[tunneltab[index+3]],
*p++=t[tunneltab[index+4]]<<24 | t[tunneltab[index+5]]<<16 |
t[tunneltab[index+6]]<<8 | t[tunneltab[index+7]],
*p++=t[tunneltab[index+8]]<<24 | t[tunneltab[index+9]]<<16 |
t[tunneltab[index+10]]<<8 | t[tunneltab[index+11]],
*p++=t[tunneltab[index+12]]<<24| t[tunneltab[index+13]]<<16 |
t[tunneltab[index+14]]<<8 | t[tunneltab[index+15]],
index+=16;
}
void changepalette(struct awdisplay *display,
struct awchunky *chunky,ULONG *palette,ULONG palentries) {
ULONG x;
ULONG *c;
/* clear chunky and force it visible. this is to
avoid nasty gfx glitch in screen mode. */
x=(chunky->width_align>>4)*chunky->height;
c=(ULONG *)chunky->framebuffer;
while (x--) *c++=0,*c++=0,*c++=0,*c++=0;
awrenderchunky_show(display,chunky);
awsetpalette(display,palette,palentries);
}
ULONG myidcmp(struct IntuiMessage *msg) {
switch (msg->Class) {
case IDCMP_RAWKEY:
printf("myidcmp: rawkey 0x%02x\n",msg->Code);
break;
case IDCMP_VANILLAKEY:
printf("myidcmp: vanillakey %c (%d)\n",
((msg->Code>31)&&(msg->Code<127))?msg->Code:'.',msg->Code);
break;
}
return AWIDHA_NOP;
}
#if defined(__SASC)
const char Version[] = "$VER: " AWINDEMOVERSION " " __AMIGADATE__ ;
#else
const char Version[] = "$VER: " AWINDEMOVERSION " (" __DATE__ ")";
#endif
int main(void) {
struct awfile *bunnypic,*bunnypal,*glas2pal;
struct awchunky *tunchunky,*rotchunky,*plasmachunky;
struct awdisplay *display;
struct awtimer *timer;
struct awodargs odargs;
struct awrdargs *rdargs;
LONG array[4]={0};
ULONG rottime,tuntime,plasmatime;
ULONG ticks,inputticks=0,time,timebase;
ULONG frames=0,took,fps100,rotpal=0,tunpal=0;
ULONG alpha=0,quit=0;
LONG *sintab;